<?php

#region 模板工具函数函数
/**
 * 获取客户端IP地址
 * @return mixed
 */
function get_ip()
{
    static $ip = null;
    if ($ip !== null) return $ip;
    if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
        $pos = array_search('unknown', $arr);
        if (false !== $pos) unset($arr[$pos]);
        $ip = trim($arr[0]);
    } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
        $ip = $_SERVER['HTTP_CLIENT_IP'];
    } elseif (isset($_SERVER['REMOTE_ADDR'])) {
        $ip = $_SERVER['REMOTE_ADDR'];
    }
    return $ip;
}

/**
 * 生成一个唯一的标识码
 * @return string
 */
function guid()
{
    if (function_exists('com_create_guid')) {
        return str_replace("-", "", str_replace("}", "", str_replace("{", "", com_create_guid())));
    } else {
        mt_srand((double)microtime() * 10000); //optional for php 4.2.0 and up.
        $charid = strtoupper(md5(uniqid(rand(), true)));
        $uuid = substr($charid, 0, 8)
            . substr($charid, 8, 4)
            . substr($charid, 12, 4)
            . substr($charid, 16, 4)
            . substr($charid, 20, 12);
        return $uuid;
    }
}


function security_encript($str)
{
    import("ORG.Crypt.Des");
    $keyval = C('AUTO_GENERATOR_KEY'); //加密过程中使用的密钥
    $userval = session("identity"); //用户ID
    $ipval = get_ip(); //获取
    $type = C('AUTO_GENERATOR_TYPE'); //加密的类型
    $timeval = C('AUTO_GENERATOR_TIMEOUT'); //加密的时间信息
    $ip = $type === "ip" || $type === "all"; //是否进行IP限制
    $user = $type === "user" || $type === "all"; //是否进行用户限制限制
    $result = $user ? "1" : "0";
    $result .= $ip ? "1" : "0";
    $result .= chr(strlen($str));
    $result .= $str;
    if ($user) {
        $result .= $userval;
        $pad = 64 - strlen($userval);
        $result .= str_repeat(chr($pad), $pad);
    }
    if ($ip) {
        $result .= $ipval;
        $pad = 128 - strlen($ipval);
        $result .= str_repeat(chr($pad), $pad);
    }
    return base64_encode(Des::encrypt($result, $keyval, $timeval));
}

/**
 * 根据配置解密字符串
 * @param $str
 * @return null|string
 */
function  security_decrypt($str)
{
    import("ORG.Crypt.Des");
    $keyval = C('AUTO_GENERATOR_KEY'); //加密过程中使用的密钥
    $result = Des::decrypt(base64_decode($str), $keyval);
    if (empty($result)) {
        return "";
    }
    $pos = 0;
    $user = $result{$pos++};
    $ip = $result{$pos++};
    $len = ord($result{$pos++});
    $str = substr($result, $pos, $len);
    $pos += $len;
    if ($user) {
        $userval = substr($result, $pos, 64);
        $pos += 64;
        $pad = ord($userval{strlen($userval) - 1});
        if ($pad > strlen($userval)) {
            return "";
        }
        if (strspn($userval, chr($pad), strlen($userval) - $pad) != $pad) {
            return "";
        }
        if (substr($userval, 0, -1 * $pad) !== session("identity")) {
            return "";
        }
    }
    if ($ip) {
        $ipval = substr($result, $pos, 128);
        $pad = ord($ipval{strlen($ipval) - 1});
        if ($pad > strlen($ipval)) {
            return "";
        }
        if (strspn($ipval, chr($pad), strlen($ipval) - $pad) != $pad) {
            return "";
        }
        if (substr($ipval, 0, -1 * $pad) !== get_ip()) {
            return "";
        }
    }
    return $str;
}

/**
 * @param string $name 表单名
 * @param array $list 简单变量数组或者对象数组
 * @param string $select 表示默认的value值
 * @param string $idkey 如果是对象数组，表示option的value对应的属性名
 * @param string $valuekey 如果是对象数组，表示option的text对应的属性名
 * @param string $default 表示默认提示字符串，如果为空，则不显示
 * @param array $attrs select的其它属性
 * @return string
 */
function html_dropdownlist($name, $list, $select = "", $idkey = "", $valuekey = "", $default = "", $attrs = array())
{
    $result = "<select ";
    $attrs["name"] = $name;
    foreach ($attrs as $key => $value) {
        $result .= "$key=\"$value\" ";
    }
    $result .= ">\n";
    if (!empty($default)) {
        $result .= "    <option value=''>$default</option>\n";
    }
    foreach ($list as $value) {
        if (is_object($value)) {
            $keyitem = $value->$idkey;
            $valueitem = $value->$valuekey;
            $check = $select == $keyitem ? "selected='selected'" : "";
        } else {
            $keyitem = $value;
            $valueitem = $value;
            $check = $select == $keyitem ? "selected='selected'" : "";
        }
        $result .= "    <option " . $check . " value='$keyitem'>$valueitem</option>\n";
    }
    $result .= "</select>";
    return $result;
}

/**
 * @param string $img 图片连接
 * @param string $noimage 返回的默认图片
 * @param bool $isrelative 是否返回相对路径（true 相对路径为相对于index.php或api.php的路径，false返回带http的绝对路径）
 * @return string
 */
function html_image_fix($img, $noimage = 'Images/nopicture.png', $isrelative = true)
{
    $img = $img ? $img : ($noimage ? $noimage : 'Images/nopicture.png');
    if($isrelative || stripos($img,"http://")===0  ){
        return $img;
    }
    return 'http://' . $_SERVER['SERVER_NAME'].':'.$_SERVER["SERVER_PORT"]. str_replace("api.php", "", $_SERVER['SCRIPT_NAME']) . $img;
}

#endregion 模板工具函数函数

#region 通用函数
function device_check()
{
    $agent = addslashes($_SERVER['HTTP_USER_AGENT']); //获取用户的UA
    //排除Window 桌面系统 和 苹果桌面系统
    if (strpos($agent, "Windows NT", 0) !== FALSE && !strpos($agent, "ARM", 0) !== FALSE || strpos($agent, "Macintosh", 0) !== FALSE) {
        //判断为PC操作系统，忽略linux桌面主机
        return 'desktop';
    }
    //判断蜘蛛程序
    if ($agent == '' || strpos($agent, "Googlebot", 0) !== FALSE || strpos($agent, "spider", 0) !== FALSE) {
        return 'spider';
    }
    //判断苹果、安卓和微软的手机客户端
    if (strpos($agent, "iPhone", 0) !== FALSE || strpos($agent, "iPod", 0) !== FALSE || strpos($agent, "iPod", 0) !== FALSE || strpos($agent, "Windows Phone", 0) !== FALSE || strpos($agent, "MQQBrowser", 0) !== FALSE || strpos($agent, "Android", 0) !== FALSE && strpos($agent, "Mobile", 0) !== FALSE) {
        return "phone";
    }
    //判断IPAD、Windows 8 ARM PAD和其它安卓系统
    if (strpos($agent, "iPad", 0) !== FALSE || strpos($agent, "Android", 0) !== FALSE || strpos($agent, "Windows NT", 0) && strpos($agent, "ARM", 0) !== FALSE) {
        return 'pad';
    }
    return "classic"; //判断为古典浏览器
}

/**
 * 上传文件
 */
function upload($dir = "other", $size = "", $types = null)
{
    import("ORG.Util.Uploader");
    $config = array(
        "savePath" => "Uploads/" . $dir, //保存路径
        "allowFiles" => $types, //文件允许格式
        "maxSize" => $size, //文件大小限制，单位KB
    );
    // 引用上传类
    $upload = new Uploader("upfile", $config); // 文件大小限制、检验后缀
    return $upload->getFileInfo();
}

/**
 * @param string $src_file 原图片路径
 * @param int $new_width 裁剪后图片宽度（当宽度超过原图片宽度时，去原图片宽度）
 * @param int $new_height 裁剪后图片高度（当宽度超过原图片宽度时，去原图片高度）
 * @param int $type 裁剪方式，1-方位模式裁剪 2-扩展原图并填充空白；；3-定点模式裁剪。
 * @param int $pos 裁剪或者扩展时的起始方位（当选定点模式裁剪时，此参数不起作用）
 *                                      1为顶端居左，2为顶端居中，3为顶端居右；
 *                                      4为中部居左，5为中部居中，6为中部居右；
 *                                      7为底端居左，8为底端居中，9为底端居右；
 * @param int $start_x 起始位置X，定点模式裁剪时生效
 * @param int $start_y 起始位置Y，定点模式裁剪时生效
 * @param int $end_x 结束位置X，定点模式裁剪时生效
 * @param int $end_y 结束位置Y，定点模式裁剪时生效
 * @return string                   目标图片路径
 */
function image_thumb($src_file, $new_width = 0, $new_height = 0, $type = 0, $pos = 5, $start_x = 0, $start_y = 0, $end_x = 0, $end_y = 0)
{
    //检查源文件
    if (!file_exists($src_file)) {
        return array("success" => false, "message" => "源文件不存在！");
    }
    //图像类型检查
    $img_type = exif_imagetype($src_file);
    $support_type = array(IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_GIF);
    if (!in_array($img_type, $support_type, true)) {
        return array("success" => false, "message" => "只支持jpg、png、gif格式图片裁剪！");
    }
    /* 载入图像 */
    switch ($img_type) {
        case IMAGETYPE_JPEG :
            $src_img = imagecreatefromjpeg($src_file);
            break;
        case IMAGETYPE_PNG :
            $src_img = imagecreatefrompng($src_file);
            break;
        case IMAGETYPE_GIF :
            $src_img = imagecreatefromgif($src_file);
            break;
        default:
            return array("success" => false, "message" => "载入图像错误！");
    }

    /* 获取源图片的宽度和高度 */
    $src_width = imagesx($src_img);
    $src_height = imagesy($src_img);
    if ($new_width < 1) {
        $new_width = $src_width;
        $new_height = $src_height;
    }
    if ($type == 3) {
        $mid_width = $end_x - $start_x; //算出要裁切的大小
        $mid_height = $end_y - $start_y; //算出要裁切的大小
        if (min($start_x, $start_y, $end_x, $end_y, $mid_width, $mid_height, 0) != 0 || $end_x > $src_width || $end_y > $src_height) {
            return array("success" => false, "message" => "输入的参数非法！");
        }
    } elseif ($type == 1) {
        $widthpoi = $src_width / $new_width;
        $heightpoi = $src_height / $new_height;
        if ($widthpoi > $heightpoi) {
            $mid_height = $src_height;
            $mid_width = $heightpoi * $new_width;
        } else {
            $mid_width = $src_width;
            $mid_height = $widthpoi * $new_height;
        }
        switch ($pos) {
            case 1: //1为顶端居左
                $start_x = 0;
                $start_y = 0;
                break;
            case 2: //2为顶端居中
                $start_x = ($src_width - $mid_width) / 2;
                $start_y = 0;
                break;
            case 3: //3为顶端居右
                $start_x = $src_width - $mid_width;
                $start_y = 0;
                break;
            case 4: //4为中部居左
                $start_x = 0;
                $start_y = ($src_height - $mid_height) / 2;
                break;
            case 5: //5为中部居中
                $start_x = ($src_width - $mid_width) / 2;
                $start_y = ($src_height - $mid_height) / 2;
                break;
            case 6: //6为中部居右
                $start_x = $src_width - $mid_width;
                $start_y = ($src_height - $mid_height) / 2;
                break;
            case 7: //7为底端居左
                $start_x = 0;
                $start_y = $src_height - $mid_height;
                break;
            case 8: //8为底端居中
                $start_x = ($src_width - $mid_width) / 2;
                $start_y = $src_height - $mid_height;
                break;
            case 9: //9为底端居右
                $start_x = $src_width - $mid_width;
                $start_y = $src_height - $mid_height;
                break;
            default: //随机
                break;
        }
    } elseif ($type == 2) {
        $widthpoi = $src_width / $new_width;
        $heightpoi = $src_height / $new_height;
        if ($widthpoi < $heightpoi) {
            $mid_height = $src_height;
            $mid_width = $new_width * $heightpoi;
        } else {
            $mid_width = $src_width;
            $mid_height = $new_height * $widthpoi;
        }
        switch ($pos) {
            case 1: //1为顶端居左
                $start_x = 0;
                $start_y = 0;
                break;
            case 2: //2为顶端居中
                $start_x = ($mid_width - $src_width) / 2;
                $start_y = 0;
                break;
            case 3: //3为顶端居右
                $start_x = $mid_width - $src_width;
                $start_y = 0;
                break;
            case 4: //4为中部居左
                $start_x = 0;
                $start_y = ($mid_height - $src_height) / 2;
                break;
            case 5: //5为中部居中
                $start_x = ($mid_width - $src_width) / 2;
                $start_y = ($mid_height - $src_height) / 2;
                break;
            case 6: //6为中部居右
                $start_x = $mid_width - $src_width;
                $start_y = ($mid_height - $src_height) / 2;
                break;
            case 7: //7为底端居左
                $start_x = 0;
                $start_y = $mid_height - $src_height;
                break;
            case 8: //8为底端居中
                $start_x = ($mid_width - $src_width) / 2;
                $start_y = $mid_height - $src_height;
                break;
            case 9: //9为底端居右
                $start_x = $mid_width - $src_width;
                $start_y = $mid_height - $src_height;
                break;
            default: //随机
                break;
        }
    } else {
        $start_x = 0;
        $start_y = 0;
        $mid_height = $src_height;
        $mid_width = $src_width;
    }
    // 为剪切图像创建背景画板
    $mid_img = imagecreatetruecolor($mid_width, $mid_height);
    if ($type == 2) {
        $color = imagecolorallocate($mid_img, 255, 255, 255);
        imagefill($mid_img, 0, 0, $color);
        imageColorTransparent($mid_img, $color);
        //拷贝剪切的图像数据到画板，生成剪切图像
        imagecopy($mid_img, $src_img, $start_x, $start_y, 0, 0, $src_width, $src_height);
    } else {
        //拷贝剪切的图像数据到画板，生成剪切图像
        imagecopy($mid_img, $src_img, 0, 0, $start_x, $start_y, $mid_width, $mid_height);
    }
    // 为裁剪图像创建背景画板
    $new_img = imagecreatetruecolor($new_width, $new_height);
    //拷贝剪切图像到背景画板，并按比例裁剪
    imagecopyresampled($new_img, $mid_img, 0, 0, 0, 0, $new_width, $new_height, $mid_width, $mid_height);
    $pathinfo = pathinfo($src_file);
    if ($type == 0) {
        $dst_file = $pathinfo['dirname'] . '/' . $pathinfo['filename'] . ".png";
    } else {
        $dst_file = $pathinfo['dirname'] . '/' . $pathinfo['filename'] . '_' . $new_width . '_' . $new_height . ".png";
    }
    if (file_exists($dst_file)) {
        unlink($dst_file);
    }
    imagepng($new_img, $dst_file, 9);
    if ($type == 0) {
        unlink($src_file);
    }
    return array("success" => true, "message" => "上传成功！", "url" => ltrim($dst_file, '.'));
}

/**
 * 遍历获取目录下的指定类型的文件
 * @param $path
 * @param array $files
 * @return array
 */
function getfiles($path, &$files = array())
{
    if (!is_dir($path)) return null;
    $handle = opendir($path);
    while (false !== ($file = readdir($handle))) {
        if ($file != '.' && $file != '..') {
            $path2 = $path . '/' . $file;
            if (is_dir($path2)) {
                getfiles($path2, $files);
            } else {
                if (preg_match("/\.(gif|jpeg|jpg|png|bmp)$/i", $file)) {
                    $files[] = $path2;
                }
            }
        }
    }
    return $files;
}
#endregion 通用函数





